from typing import List
import coreapi
import coreschema
from rest_framework.schemas import ManualSchema, AutoSchema
from django.http import Http404
from rest_framework import generics, filters, viewsets
from rest_framework import permissions
from rest_framework.throttling import AnonRateThrottle, UserRateThrottle
from rest_framework.views import APIView
from utils.custom_json_response import JsonResponse
from datetime import datetime
from django.utils.translation import gettext_lazy as _
import logging
logger = logging.getLogger("django")

"""
在python3中使用super().超类方法()  时
不行传递self本身给父类方法，其他参数按顺序传递，例如：
    def get(self, request, *args, **kwargs):
        return super().get(request, *args, **kwargs)
"""

class ListCreateAPIView(generics.ListCreateAPIView):
    """
    封装获取数据列表，创建数据序列化视图
    """

    # 只有认证登录后，才能访问
    permission_classes = [permissions.IsAuthenticated, ]

    # 限制请求频率
    throttle_class = (AnonRateThrottle, UserRateThrottle)

    # 过滤，设置固定字段
    filter_backends = ()
    filter_class = None

    # 数据集
    queryset = None

    # 排序
    ordering_fields = ["id", ]  # 可排序字段
    ordering = ('id',)  # 默认排序
    filters.OrderingFilter.ordering_description = _('排序，默认为 id 字段排序，可使用 id 字段排序，倒序使用请在字段前加 负号（-）')

    # 序列化
    serializer_class = None

    # 模型
    model = None

    # 重写获取列表方法
    def list(self, request, *args, **kwargs):

        # 过滤
        queryset = self.filter_queryset(self.get_queryset())
        # 分页
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            return self.get_paginated_response(serializer.data)

        serializer = self.get_serializer(queryset, many=True)
        return JsonResponse(data=serializer.data, code=200, msg="success")

    # 重写创建方法
    def create(self, request, *args, **kwargs):
        # request.data["create_user"] = request.user.id
        data = request.data
        if self.model:
            data = self.model.format_request_data(data)
        print(data)
        serializer = self.get_serializer(data=data)
        # raise_exception=True 如果数据验证失败，则直接抛出异常，到settings.EXCEPTION_HANDLER自定义异常处理
        # raise_exception=False 则不抛出异常，如何验证失败，则返回False，反之True
        if serializer.is_valid(raise_exception=False):
            self.perform_create(serializer)
            return JsonResponse(data=serializer.data, msg="success", code=200)
        logger.error(serializer.errors)
        return JsonResponse(data=serializer.errors, msg="success", code=400)


class DeleteApiView(APIView):
    """
    批量删除
    """

    # 只有认证登录后，才能访问
    permission_classes = [permissions.IsAuthenticated, ]

    model = None

    schema = AutoSchema(
        manual_fields=[
            coreapi.Field("ids", required=True, location="body", schema=coreschema.Array()),
        ]
    )

    def get_obj(self, id):
        try:
            obj = self.model.objects.get(id=id)
            return obj
        except:
            raise Http404

    def delete(self, request, *args, **kwargs):
        for id in request.data["ids"]:
            obj = self.get_obj(id)
            obj.delete()

        return JsonResponse(msg="success", code=200)


class DetailApiView(generics.RetrieveDestroyAPIView):
    """
    详情序列化视图
    """

    # 只有认证登录后，才能访问
    permission_classes = [permissions.IsAuthenticated, ]

    # 限制请求频率
    throttle_class = (AnonRateThrottle, UserRateThrottle)

    # 序列化
    serializer_class = None

    # 模型
    model = None

    def get_obj(self, id):
        try:
            obj = self.model.objects.get(id=id)
            return obj
        except:
            raise Http404

    # 获取详细信息
    def get(self, request, *args, **kwargs):
        obj = self.get_obj(kwargs.get('id'))
        serializer = self.serializer_class(obj, context={'request': request})
        return JsonResponse(data=serializer.data, code=200, msg="success")

    # 更改单个
    def put(self, request, *args, **kwargs):
        request.data["update_time"] = datetime.now()
        data = request.data
        if self.model:
            data = self.model.format_request_data(data)
        obj = self.get_obj(kwargs.get('id'))
        serializer = self.serializer_class(obj, data=data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return JsonResponse(data=serializer.data, code=200, msg="success")
        # logger.error(serializer.errors)
        return JsonResponse(data=serializer.errors, code=400, msg="success")

    # 删除单个
    def delete(self, request, *args, **kwargs):
        obj = self.get_obj(kwargs.get('id'))
        obj.delete()
        return JsonResponse(code=200, msg="success")